import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pp_uikit/pp_uikit_constants.dart';
import 'package:pp_uikit/text_input_formatter/int_range_text_input_formatter.dart';
import 'package:pp_uikit/theme/pp_default_theme.dart';

typedef OnValueChanged = void Function(int oldValue, int newValue);

enum PPSteperStyle {
  centerInput,
  leftInput,
}

// ignore: must_be_immutable
class PPSteper extends StatefulWidget {
  /// 录入项 是否可编辑
  final bool isEdit;

  /// 特有字段
  final int? value;

  /// 单步上限值
  final int maxLimit;

  /// 单步下限值
  final int minLimit;

  /// 当前值变化回调
  final OnValueChanged? onChanged;

  /// 是否可通过键盘手动输入内容
  final bool canManualInput;

  final TextEditingController? controller;

  /// 背景色
  final Color? backgroundColor;

  /// 按钮颜色
  Color? buttonColor;

  /// 边框色
  final Color borderColor;

  final double borderWidth;

  final PPSteperStyle style;

  double? height;

  double fontSize;

  PPSteper({
    Key? key,
    this.isEdit = true,
    this.value,
    this.maxLimit = 99999,
    this.minLimit = 0,
    this.onChanged,
    this.canManualInput = true,
    this.controller,
    this.backgroundColor,
    this.buttonColor,
    this.height,
    this.fontSize = 14,
    this.borderColor = const Color(0xFFE3E3E3),
    this.borderWidth = 0.5,
    this.style = PPSteperStyle.centerInput,
  }) : super(key: key) {
    if (value != null) {
      assert(value! >= minLimit && value! <= maxLimit);
    }
    if (controller != null) {
      int? defaultValue = int.tryParse(controller!.text);
      assert(
          defaultValue == null ||
              (defaultValue >= minLimit && defaultValue <= maxLimit),
          'The text or value in the controller is not in the limits.');
    }
    if (style == PPSteperStyle.leftInput) {
      height ??= 36;
      buttonColor ??= PPDefaultTheme.instance.brandPrimary;
      fontSize = 16;
    }
  }

  @override
  PPSeperState createState() {
    return PPSeperState();
  }
}

class PPSeperState extends State<PPSteper> {
  late TextEditingController _textEditingController;
  late int _oldValue;
  int get _value => int.tryParse(_textEditingController.text) ?? 0;

  set _value(int value) {
    // 如果是通过代码设置TextField的值，就将光标移动到最后
    _textEditingController.value = TextEditingValue(
        text: value.toString(),
        selection: TextSelection.fromPosition(
            TextPosition(offset: value.toString().length)));
  }

  @override
  void initState() {
    super.initState();
    if (widget.controller == null) {
      _textEditingController = TextEditingController();
      _textEditingController.text = (widget.value ?? 0).toString();
    } else {
      _textEditingController = widget.controller!;
    }
    _oldValue = _value;
    _textEditingController.addListener(_onControllerTextChangedHandleTicker);
  }

  @override
  void dispose() {
    _textEditingController.removeListener(_onControllerTextChangedHandleTicker);
    super.dispose();
  }

  void _onControllerTextChangedHandleTicker() {
    if (_oldValue != _value) {
      if (widget.onChanged != null) {
        widget.onChanged!(_oldValue, _value);
      }
      setState(() {});
      _oldValue = _value;
    }
  }

  @override
  Widget build(BuildContext context) {
    if (widget.style == PPSteperStyle.leftInput) {
      return _buildLeftStyleWidget();
    }
    return _buildCenterStyleWidget();
  }

  Widget _buildCenterStyleWidget() {
    return Container(
      decoration: BoxDecoration(
        borderRadius: const BorderRadius.all(Radius.circular(4)),
        border: Border.all(
          width: widget.borderWidth,
          color: widget.borderColor,
        ),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          GestureDetector(
            onTap: () {
              if (!widget.isEdit) {
                return;
              }
              _checkReachMinLevel();
            },
            child: SizedBox(
              width: widget.height,
              height: widget.height,
              child: Center(child: _getMinusIcon()),
            ),
          ),
          Container(
            color: widget.borderColor,
            width: widget.borderWidth,
            height: widget.height ?? 24,
          ),
          Expanded(child: _buildValueWidget()),
          Container(
            color: widget.borderColor,
            width: widget.borderWidth,
            height: widget.height ?? 24,
          ),
          GestureDetector(
            onTap: () {
              if (!widget.isEdit) {
                return;
              }
              _checkReachMaxLevel();
            },
            child: SizedBox(
              width: widget.height,
              height: widget.height,
              child: Center(child: _getAddIcon()),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildLeftStyleWidget() {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Expanded(
          child: Container(
            height: widget.height,
            decoration: BoxDecoration(
              color: PPDefaultTheme.instance.backgroundColor,
              borderRadius: const BorderRadius.all(Radius.circular(4)),
            ),
            child: _buildValueWidget(),
          ),
        ),
        GestureDetector(
          onTap: () {
            if (!widget.isEdit) {
              return;
            }
            _checkReachMinLevel();
          },
          child: Container(
            width: widget.height,
            height: widget.height,
            margin: const EdgeInsets.only(left: 4),
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.all(Radius.circular(4)),
              border: Border.all(
                width: 1,
                color: widget.borderColor,
              ),
            ),
            child: Center(child: _getMinusIcon()),
          ),
        ),
        GestureDetector(
          onTap: () {
            if (!widget.isEdit) {
              return;
            }
            _checkReachMaxLevel();
          },
          child: Container(
            width: widget.height,
            height: widget.height,
            margin: const EdgeInsets.only(left: 4),
            decoration: BoxDecoration(
              borderRadius: const BorderRadius.all(Radius.circular(4)),
              border: Border.all(
                width: 1,
                color: widget.borderColor,
              ),
            ),
            child: Center(child: _getAddIcon()),
          ),
        ),
      ],
    );
  }

  Image _getAddIcon() {
    if (!widget.isEdit) {
      return Image.asset(
        "images/icon_steper_add_disable.png",
        width: 24,
        height: 24,
        package: PPUIKitConstant.packageName,
      );
    }

    if (_isReachMaxLevel()) {
      return Image.asset(
        "images/icon_steper_add_disable.png",
        width: 24,
        height: 24,
        package: PPUIKitConstant.packageName,
      );
    }

    return Image.asset(
      "images/icon_steper_add.png",
      width: 24,
      height: 24,
      color: widget.buttonColor,
      package: PPUIKitConstant.packageName,
    );
  }

  Image _getMinusIcon() {
    if (!widget.isEdit) {
      return Image.asset(
        "images/icon_steper_minus_disable.png",
        width: 24,
        height: 24,
        package: PPUIKitConstant.packageName,
      );
    }

    if (_isReachMinLevel()) {
      return Image.asset(
        "images/icon_steper_minus_disable.png",
        width: 24,
        height: 24,
        package: PPUIKitConstant.packageName,
      );
    }

    return Image.asset(
      "images/icon_steper_minus.png",
      width: 24,
      height: 24,
      package: PPUIKitConstant.packageName,
      color: widget.buttonColor,
    );
  }

  Widget _buildValueWidget({Decoration? decoration}) {
    if (widget.canManualInput) {
      return Container(
        alignment: Alignment.center,
        width: 50,
        decoration: decoration,
        child: TextField(
          maxLines: 1,
          minLines: 1,
          enabled: widget.isEdit,
          textAlign: TextAlign.center,
          controller: _textEditingController,
          keyboardType:
              widget.minLimit < 0 ? TextInputType.text : TextInputType.number,
          inputFormatters: [
            widget.minLimit < 0
                ?
                // PPTextInputFormatter.all
                FilteringTextInputFormatter.allow(
                    RegExp(r'-|[1-9]\d*|-[1-9]\d*')) // 允许一个开头的减号
                : FilteringTextInputFormatter.digitsOnly,
            IntRangeTextInputFormatter(
                minValue: widget.minLimit, maxValue: widget.maxLimit)
          ],
          style: TextStyle(
            color: widget.style == PPSteperStyle.leftInput
                ? PPDefaultTheme.instance.brandPrimary
                : PPDefaultTheme.instance.colorTextBase,
            fontSize: widget.fontSize,
          ),
          decoration: InputDecoration(
            hintText: '0',
            hintStyle: TextStyle(
              color: const Color(0xFFCCCCCC),
              fontSize: widget.fontSize,
            ),
            border: InputBorder.none,
            contentPadding: const EdgeInsets.all(0),
            isDense: true,
          ),
        ),
      );
    } else {
      return Container(
        alignment: Alignment.center,
        width: 50,
        decoration: decoration,
        child: Text(
          "$_value",
          style: const TextStyle(
            color: Color(0xFF222222),
            fontSize: 14,
          ),
        ),
      );
    }
  }

  void _checkReachMinLevel() {
    if (!_isReachMinLevel()) {
      _value = _value - 1;
      return;
    }
  }

  void _checkReachMaxLevel() {
    if (!_isReachMaxLevel()) {
      _value = _value + 1;
      return;
    }
  }

  bool _isReachMinLevel() {
    if (_value <= widget.minLimit) {
      return true;
    }
    return false;
  }

  bool _isReachMaxLevel() {
    if (_value >= widget.maxLimit) {
      return true;
    }
    return false;
  }
}
